/*
 * StartApplication.java
 *
 * Created on Apr 13, 2010 11:57:48 AM;
 */

package org.sunspotworld;

import com.sun.spot.io.j2me.radiogram.Radiogram;
import com.sun.spot.io.j2me.radiogram.RadiogramConnection;
import com.sun.spot.peripheral.ISleepManager;
import com.sun.spot.peripheral.Spot;
import com.sun.spot.peripheral.radio.IRadioPolicyManager;
import com.sun.spot.resources.transducers.ISwitch;
import com.sun.spot.resources.transducers.ITriColorLED;
import com.sun.spot.resources.transducers.LEDColor;

import com.sun.spot.sensorboard.EDemoBoard;
import com.sun.spot.sensorboard.peripheral.IAccelerometer3D;
import com.sun.spot.service.BootloaderListenerService;
import com.sun.spot.util.Utils;

import java.io.IOException;
import javax.microedition.io.Connector;

import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

/**
 * The startApp method of this class is called by the VM to start the
 * application.
 *
 * The manifest specifies this class as MIDlet-1, which means it will
 * be selected for execution.
 */
public class StartApplication extends MIDlet {

    private ITriColorLED [] leds = EDemoBoard.getInstance().getLEDs();
    private ISwitch[] sw = EDemoBoard.getInstance().getSwitches();

    private boolean pressed = false;

    private int driveDir = 0;
    private int steerDir = 0;
    private int dutyCycle = 80;
    private int tiltY = 0;
    private int tiltX = 0;

    private String port = "51";

    private IAccelerometer3D accel = EDemoBoard.getInstance().getAccelerometer();

    private ISleepManager sleep = Spot.getInstance().getSleepManager();

    protected void startApp() throws MIDletStateChangeException {
        new BootloaderListenerService().start();

        sleep.disableDeepSleep();

        IRadioPolicyManager rpm = Spot.getInstance().getRadioPolicyManager();
        rpm.setChannelNumber(25);
        rpm.setOutputPower(0);

        RadiogramConnection dgConnection = null;
        Radiogram dg = null;

        try {
                dgConnection = (RadiogramConnection) Connector.open("radiogram://broadcast:" + port);
                dg = (Radiogram)dgConnection.newDatagram(dgConnection.getMaximumLength());
        } catch (IOException ex) {
                ex.printStackTrace();
        }

        while(sw[0].isOpen() || sw[1].isOpen()) {

            if((sw[0].isClosed() && sw[1].isOpen()) && !pressed) {
                if((dutyCycle - 22) >= 80) {
                    dutyCycle -= 22;
                }
                pressed = true;
            }
            else if((sw[0].isOpen() && sw[1].isClosed()) && !pressed) {
                if((dutyCycle + 22) <= 256) {
                    dutyCycle += 22;
                }
                pressed = true;
            }
            else if(sw[0].isOpen() && sw[1].isOpen()) {
                pressed = false;
            }

            for(int i = 0; i < ((dutyCycle-80)/22); i++) {
                leds[i].setColor(LEDColor.GREEN);
                leds[i].setOn();
            }

            try {
                tiltX = (int)Math.toDegrees(accel.getTiltX());
                tiltY = (int)Math.toDegrees(accel.getTiltY());
            } catch(IOException ex) {
                ex.printStackTrace();
            }

            if(tiltX >= -15 && tiltX <= 15) {
                steerDir = 1;
            }
            else if(tiltX > 25) {
                steerDir = 0;
            }
            else if(tiltX < -25) {
                steerDir = 2;
            }

            if(tiltY >= -15 && tiltY <= 15) {
                driveDir = 1;
            }
            else if(tiltY > 25) {
                driveDir = 2;
            }
            else if(tiltY < -25) {
                driveDir = 0;
            }

            try {
                dg.reset();
                dg.writeInt(driveDir);
                dg.writeInt(steerDir);
                dg.writeInt(dutyCycle);
                dgConnection.send(dg);

            } catch (IOException ex) {
                ex.printStackTrace();
            }

            System.out.println("~~~~~~~~~~~~~~~~~~~~");
            System.out.println("Drive Direction: " + driveDir);
            System.out.println("Steer Direction: " + steerDir);
            System.out.println("Duty Cycle: " + dutyCycle);
            System.out.println("X Tilt: " + tiltX);
            System.out.println("Y Tilt: " + tiltY);
            System.out.println("~~~~~~~~~~~~~~~~~~~~");

            for(int i = 0; i < leds.length; i++) {
                leds[i].setOff();
            }
        }
        notifyDestroyed();                      // cause the MIDlet to exit
    }

    protected void pauseApp() {
        // This is not currently called by the Squawk VM
    }

    /**
     * Called if the MIDlet is terminated by the system.
     * I.e. if startApp throws any exception other than MIDletStateChangeException,
     * if the isolate running the MIDlet is killed with Isolate.exit(), or
     * if VM.stopVM() is called.
     *
     * It is not called if MIDlet.notifyDestroyed() was called.
     *
     * @param unconditional If true when this method is called, the MIDlet must
     *    cleanup and release all resources. If false the MIDlet may throw
     *    MIDletStateChangeException  to indicate it does not want to be destroyed
     *    at this time.
     */
    protected void destroyApp(boolean unconditional) throws MIDletStateChangeException {
        for (int i = 0; i < 8; i++) {
            leds[i].setOff();
        }
    }
}
